﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using iMobileDevice;
using iMobileDevice.iDevice;
using iMobileDevice.Lockdown;
using iMobileDevice.Service;
using System.Threading;
using System.IO;
using AIWhitelist.Framework.Common;

namespace AIWhitelist
{
    public partial class frmMain : Form
    {
        frmMap map = new frmMap();
        LocationService service;
        public string filepath = "D:\\chrome downloads\\iOSRelease\\points.txt";
        public double lafactor = 1;
        public double lofactor = 1;
        public frmMain()
        {
            InitializeComponent();
        }
        private void frmMain_Load(object sender, EventArgs e)
        {
            NativeLibraries.Load();
            service = LocationService.GetInstance();
            service.PrintMessageEvent = PrintMessage;
            service.ListeningDevice();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            map.ShowDialog();
            txtLocation.Text = $"{map.Location.Longitude} : {map.Location.Latitude}";
        }

        private void button2_Click(object sender, EventArgs e)
        {
            //var location = new Location(txtLocationTest.Text);
            //service.UpdateLocation(location);
            //操场
            Location l1 = new Location(104.097832, 30.675866);
            Location l2 = new Location(104.097875, 30.675756);
            Location l3 = new Location(104.098041, 30.675617);
            Location l4 = new Location(104.098197, 30.67558);
            Location l5 = new Location(104.098293, 30.67559);
            Location l6 = new Location(104.098556, 30.675686);
            Location l7 = new Location(104.098658, 30.675853);
            Location l8 = new Location(104.098685, 30.676738);
            Location l9 = new Location(104.09861, 30.676877);
            Location l10 = new Location(104.098283, 30.677057);
            Location l11 = new Location(104.097977, 30.676955);
            Location l12 = new Location(104.097864, 30.676803);
            Location l13 = new Location(104.097837, 30.676291);
            
            rever(l1); rever(l2); rever(l3); rever(l4); rever(l5); rever(l6); rever(l7);
            rever(l8); rever(l9); rever(l10); rever(l11); rever(l12); rever(l13);
            for (int i = 0; i < 3; i++)
            {

                form_line(l1, l2);
                form_line(l2, l3);
                form_line(l3, l4);
                form_line(l4, l5);
                form_line(l5, l6);
                form_line(l6, l7);
                form_line(l7, l8);
                form_line(l8, l9);
                form_line(l9, l10);
                form_line(l10, l11);
                form_line(l11, l12);
                form_line(l12, l13);
                form_line(l13, l1);
            }
            /*
            List<Location> loclist = generate();
            int i = 0, j = 1;
            

            for (; j < loclist.Count; i++, j++) form_line(loclist[i], loclist[j]);
            //loclist.ForEach((Location t) => { service.UpdateLocation(t);Delay(500); });

            PrintMessage("finish");*/
        }

        //地球半径，单位米
        private const double EARTH_RADIUS = 6378137;
        /// <summary>
        /// 计算两点位置的距离，返回两点的距离，单位 米
        /// 该公式为GOOGLE提供，误差小于0.2米
        /// </summary>
        /// <param name="lat1">第一点纬度</param>
        /// <param name="lng1">第一点经度</param>
        /// <param name="lat2">第二点纬度</param>
        /// <param name="lng2">第二点经度</param>
        /// <returns></returns>
        public static double GetDistance(Location l1,Location l2)
        {
            double radLat1 = Rad(l1.Latitude);
            double radLng1 = Rad(l1.Longitude);
            double radLat2 = Rad(l2.Latitude);
            double radLng2 = Rad(l2.Longitude);
            double a = radLat1 - radLat2;
            double b = radLng1 - radLng2;
            double result = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a / 2), 2) + Math.Cos(radLat1) * Math.Cos(radLat2) * Math.Pow(Math.Sin(b / 2), 2))) * EARTH_RADIUS;
            result = Math.Round(result * 10000) / 10000;
            return result;
        }

        /// <summary>
        /// 经纬度转化成弧度
        /// </summary>
        /// <param name="d"></param>
        /// <returns></returns>
        private static double Rad(double d)
        {
            return (double)d * Math.PI / 180d;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public List<Location> generate()
        {
            StreamReader sr = new StreamReader(filepath);
            List<Location> loclist = new List<Location>();
            string line = sr.ReadLine();
            do
            {
                string[] sloc = line.Split(',');
                Location l = new Location(float.Parse(sloc[0]), float.Parse(sloc[1]));
                rever(l);
                loclist.Add(l);
                line = sr.ReadLine();
            } while (line != null);
            return loclist;
        }
        public static double WGSLat(double lat, double lon)
        {
            double PI = 3.14159265358979324;//圆周率
            double a = 6378245.0;//克拉索夫斯基椭球参数长半轴a
            double ee = 0.00669342162296594323;//克拉索夫斯基椭球参数第一偏心率平方
            double dLat = transformLat(lon - 105.0, lat - 35.0);
            double radLat = lat / 180.0 * PI;
            double magic = Math.Sin(radLat);
            magic = 1 - ee * magic * magic;
            double sqrtMagic = Math.Sqrt(magic);
            dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * PI);
            return (lat - dLat);
        }
        public static double transformLon(double x, double y)
        {
            double PI = 3.14159265358979324;//圆周率
            double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.Sqrt(Math.Abs(x));
            ret += (20.0 * Math.Sin(6.0 * x * PI) + 20.0 * Math.Sin(2.0 * x * PI)) * 2.0 / 3.0;
            ret += (20.0 * Math.Sin(x * PI) + 40.0 * Math.Sin(x / 3.0 * PI)) * 2.0 / 3.0;
            ret += (150.0 * Math.Sin(x / 12.0 * PI) + 300.0 * Math.Sin(x / 30.0 * PI)) * 2.0 / 3.0;
            return ret;
        }
        public static double transformLat(double x, double y)
        {
            double PI = 3.14159265358979324;//圆周率
            double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.Sqrt(Math.Abs(x));
            ret += (20.0 * Math.Sin(6.0 * x * PI) + 20.0 * Math.Sin(2.0 * x * PI)) * 2.0 / 3.0;
            ret += (20.0 * Math.Sin(y * PI) + 40.0 * Math.Sin(y / 3.0 * PI)) * 2.0 / 3.0;
            ret += (160.0 * Math.Sin(y / 12.0 * PI) + 320 * Math.Sin(y * PI / 30.0)) * 2.0 / 3.0;
            return ret;
        }

        public static void Delay(int mm)
        {
            DateTime current = DateTime.Now;
            while (current.AddMilliseconds(mm) > DateTime.Now)
            {
                Application.DoEvents();
            }
            return;
        }

        public static double WGSLon(double lat, double lon)
        {
            double PI = 3.14159265358979324;//圆周率
            double a = 6378245.0;//克拉索夫斯基椭球参数长半轴a
            double ee = 0.00669342162296594323;//克拉索夫斯基椭球参数第一偏心率平方
            double dLon = transformLon(lon - 105.0, lat - 35.0);
            double radLat = lat / 180.0 * PI;
            double magic = Math.Sin(radLat);
            magic = 1 - ee * magic * magic;
            double sqrtMagic = Math.Sqrt(magic);
            dLon = (dLon * 180.0) / (a / sqrtMagic * Math.Cos(radLat) * PI);
            return (lon - dLon);
        }

        public void rever(Location l)
        {
            l.Latitude = WGSLat(l.Latitude, l.Longitude);
            l.Longitude = WGSLon(l.Latitude, l.Longitude);
        }

        public void form_line(Location L1, Location L2)
        {
            double distance = GetDistance(L1, L2);
            int times = (int)(distance / 3);
            double dla = (L2.Latitude-L1.Latitude)/times;
            double dlo = (L2.Longitude-L1.Longitude)/times;
            for (int i = 0; i < times; i++)
            {
                service.UpdateLocation(L1);
                L1.Latitude += dla;
                L1.Longitude += dlo;
                Delay(1000);
            }
        }

        public void PrintMessage(string msg)
        {
            if (rtbxLog.InvokeRequired)
            {
                this.Invoke(new Action<string>(PrintMessage), msg);
            }
            else
            {
                rtbxLog.AppendText($"{DateTime.Now.ToString("HH:mm:ss")}： {msg}\r\n");
            }
        }

        private void btnReset_Click(object sender, EventArgs e)
        {
            service.ClearLocation();
        }
    }

}
